package cron

import (
	"bytes"
	"context"
	"fmt"
	"html/template"
	"network-state/controllers/check_url"
	"network-state/global"
	"network-state/model"
	"network-state/util"
	"network-state/util/curl"
	"network-state/util/log"
	"network-state/util/mail"
	"sync"

	"github.com/gogf/gf/v2/os/gcron"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/os/grpool"
	"github.com/gogf/gf/v2/util/gconv"
)

// 检查域名
func CheckUrl() {

	var (
		err     error
		errInfo string
		l       = log.LOG_LEVEL{}
		ctx     = gctx.New()
		spec    = global.Cfg["CRON_CHECK_URL"]
	)

	_, err = gcron.Add(ctx, spec, func(ctx context.Context) {

		// 列表数据
		cu := check_url.List()
		task(cu)
	})

	if err != nil {
		errInfo = fmt.Sprintf("CheckUrl 定时任务异常:%v", err)
		l.Log(errInfo)
		panic(err)
	}
}

// 协程任务
func task(i interface{}) {

	var (
		errInfo string
		ctx     = gctx.New()
		wg      = sync.WaitGroup{}
		l       = log.LOG_LEVEL{}
	)

	cu, ok := i.([]model.CheckUrl)
	if !ok {
		errInfo = fmt.Sprintf("断言失败,协程任务:任务参数类型错误:%v", ok)
		l.Log(errInfo)
		return
	}

	for _, v := range cu {

		wg.Add(1)

		mc := v
		grpool.Add(ctx, func(ctx context.Context) {
			StatusCode(mc)
			wg.Done()
		})

		// go func(mc model.CheckUrl) {
		// 	getCurl(mc)
		// 	wg.Done()
		// }(v)
	}

	wg.Wait()

}

// 获取状态码
func StatusCode(i interface{}) {

	var (
		errInfo string
		l       = log.LOG_LEVEL{}
	)

	cu, ok := i.(model.CheckUrl)
	if !ok {
		errInfo = fmt.Sprintf("断言失败, http.get 请求:任务参数类型错误:%v", ok)
		l.Log(errInfo)
		return
	}

	co := &curl.Options{
		Url: cu.Address,
	}
	i2 := co.GetStatusCode()
	if i2 != 200 {
		settingMail(cu, i2)
	}
}

/*
设置发送邮件
*/
func settingMail(i interface{}, StatusCode int) error {

	var (
		errInfo string
		l       = log.LOG_LEVEL{}
	)

	cu, ok := i.(model.CheckUrl)
	if !ok {
		errInfo = fmt.Sprintf("断言失败, 设置发送邮件:任务参数类型错误:%v", ok)
		l.Log(errInfo)
	}

	// 读取 html 模板文件
	byteData, err := global.HtmlTemp.ReadFile("templates/check_url.html")
	if err != nil {
		errInfo = fmt.Sprintf("读取 check_url.html 模板文件失败:%v", err)
		l.Log(errInfo)
	}

	t := template.Must(template.New("").Parse(string(byteData)))

	// 作为变量传递给html模板
	body := new(bytes.Buffer)
	t.Execute(body, struct {
		Name       string
		Address    string
		StatusCode string
		Date       string
	}{
		Name:       cu.Name,
		Address:    cu.Address,
		StatusCode: fmt.Sprint(StatusCode),
		Date:       util.GetDate(),
	})

	b := body.Bytes()
	html := string(b)

	// 发送邮件
	options := &mail.Options{
		MailHost: global.Cfg["MAIL_HOST"],
		MailPort: gconv.Int(global.Cfg["MAIL_PORT"]),
		MailUser: global.Cfg["MAIL_USER"],
		NickName: cu.Name,
		MailPass: global.Cfg["MAIL_PASS"],
		MailTo:   "1@qq.com",
		Subject:  cu.Name + " " + util.GetDate(),
		Body:     html,
	}

	err = options.Send()
	return err
}
